
AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "shared.lua" )
include( 'shared.lua' )

function ENT:Initialize()
	self:SetTrigger(true)
	self.tblOutputs = self.tblOutputs || {}
	self.tblEnts = {}
end

function ENT:GetFilterEnts()
	if !self.sFilter then return {} end
	local entFilter = ents.FindByName(self.sFilter)
	local tblFilterEnts = {}
	for k, v in pairs(entFilter) do
		local sFilterName = v:GetKeyValues()["filtername"]
		local sFilterClass = v:GetKeyValues()["filterclass"]
		if sFilterName || sFilterClass then
			local Ents
			if sFilterName then
				Ents = ents.FindByName(sFilterName)
			elseif sFilterClass then
				Ents = ents.FindByClass(sFilterClass)
			end
			table.Add(tblFilterEnts, Ents)
		end
	end
	return tblFilterEnts
end

function ENT:PassesTriggerFilters(ent)
	if self.bDisabled then
		if table.HasValue(self.tblEnts,ent) then
			for k, v in pairs(self.tblEnts) do
				if v == ent then table.remove(self.tblEnts,k); break end
			end
		end
		return false
	end
	if self.sFilter && !table.HasValue(self:GetFilterEnts(),ent) then return false end
	if self:HasSpawnflag(64) then return true end
	if ent:IsPlayer() then
		if self:HasSpawnflag(1) then return true end
		return false
	end
	if ent:IsNPC() then
		if self:HasSpawnflag(2) then return true end
		return false
	end
	if ValidEntity(ent:GetPhysicsObject()) && self:HasSpawnflag(8) then return true end
	return false
end

function ENT:StartTouch(ent)
	if !self:PassesTriggerFilters(ent) then return end
	if ent:IsPlayer() then

                if GetConVarNumber("sr_debug") == 1 then print("Func_spacerace: "..ent:Nick().." entered zone "..self.fMapZone) end

                mapZoneEnter(ent , self.fMapZone , self.fCheckpointNum)
                
		if #self.tblEnts == 0 then self:FireOutput("OnStartTouchAll",ent,ent) end
		self:FireOutput("OnStartTouch",ent,ent)
		table.insert(self.tblEnts,ent)
		return
	end
	local phys = ent:GetPhysicsObject()
	if !ValidEntity(phys) then return end

	if #self.tblEnts == 0 then self:FireOutput("OnStartTouchAll",ent,ent) end
	self:FireOutput("OnStartTouch",ent,ent)
	table.insert(self.tblEnts,ent)
end

function ENT:EndTouch(ent)
	if !self:PassesTriggerFilters(ent) then return end
	for k, v in pairs(self.tblEnts) do
		if v == ent || !ValidEntity(v) then table.remove(self.tblEnts,k) end
	end

	if ent:IsPlayer() then

                if GetConVarNumber("sr_debug") == 1 then print("Func_spacerace: "..ent:Nick().." left zone "..self.fMapZone) end
                
                mapZoneLeave(ent , self.fMapZone)
                
		self:FireOutput("OnEndTouch",ent,ent)
		if #self.tblEnts == 0 then self:FireOutput("OnEndTouchAll",ent,ent) end
		return
	end

	self:FireOutput("OnEndTouch",ent,ent)
	if #self.tblEnts == 0 then self:FireOutput("OnEndTouchAll",ent,ent) end
end

function ENT:IsCheckpoint()
    if self.fMapZone == SR_CHECKPOINT then
        return true
    else
        return false
    end
end

function ENT:OnRemove()
end

function ENT:Think()
end

function ENT:HasSpawnflag(iSpawnflag)
	return table.HasValue(self.iSpawnflags,iSpawnflag)
end

function ENT:FireOutput(sOutput,entActivator,entCaller)
	if !self.tblOutputs[sOutput] then return end
	for k, v in pairs(self.tblOutputs[sOutput]) do
		local tblOutput = string.Explode( ",", v )
		local _sOutput = tblOutput[2]
		local sParameters = tblOutput[3]
		local fDelay = tonumber(tblOutput[4])
		local iOnce = tonumber(tblOutput[5])
		if tblOutput[1] == "!activator" then
			if ValidEntity(entActivator) then entActivator:Fire(_sOutput, sParameters, fDelay) end
		elseif tblOutput[1] == "!caller" then
			if ValidEntity(entCaller) then entCaller:Fire(_sOutput, sParameters, fDelay) end
		else
			local tblEnts = ents.FindByName(tblOutput[1])
			if #tblEnts == 0 then tblEnts = ents.FindByClass(tblOutput[1]) end
			for k, v in pairs(tblEnts) do
				v:Fire(_sOutput, sParameters, fDelay)
			end
		end
		if iOnce == 1 then
			table.remove(self.tblOutputs[sOutput],k)
		end
	end
end

function ENT:KeyValue(key, value)
	if key == "StartDisabled" then
		self.bDisabled = tobool(value)
		return
	end
	if key == "spawnflags" then
		local function GetSpawnflag( value )
			local tblSpawnflags = { 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1 }
			if !table.HasValue(tblSpawnflags, value) then return false end
			return value
		end
		local function GetSpawnflags(flags)
			local tblSpawnflags = {}
			local d_flags = { 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1 }
			local bUsed
			for k, v in pairs( d_flags ) do
				if v <= flags and !bUsed then
					local value_a = v
					local value_b = flags -v
					if table.HasValue(d_flags, value_a) then
						local sk = GetSpawnflag(value_a)
						if sk then table.insert(tblSpawnflags,sk) end
					end
					if flags != v then
						if table.HasValue(d_flags, value_b) then
							bUsed = true
							local sk = GetSpawnflag(value_b)
							if sk then table.insert(tblSpawnflags,sk) end
						else
							flags = value_b
							bUsed = false
							GetSpawnflags(flags)
						end
					else
						bUsed = true
					end
				end
			end
			return tblSpawnflags
		end
		self.iSpawnflags = GetSpawnflags(tonumber(value))
		return
	end
	if key == "map_zone" then
		self.fMapZone = tonumber(value)
		return
	end
        if key == "checkpoint" then
		self.fCheckpointNum = tonumber(value)
		return
	end
	local tblOutputs = {"OnEndTouch", "OnEndTouchAll", "OnStartTouch", "OnStartTouchAll"}
	if table.HasValue(tblOutputs,key) then
		self.tblOutputs = self.tblOutputs || {}
		self.tblOutputs[key] = self.tblOutputs[key] || {}
		table.insert(self.tblOutputs[key], value)
		return
	end
end

function ENT:AcceptInput(sCvar, entActivator, entCaller)
	if sCvar == "Enable" then
		self.bDisabled = false
	elseif sCvar == "Disable" then
		self.bDisabled = true
	elseif sCvar == "Toggle" then
		if self.bDisabled then self.bDisabled = false
		else self.bDisabled = true end
        elseif sCvar == "SlayOn" then
		self.fSlay = true
        elseif sCvar == "SlayOff" then
		self.fSlay = false
	end
end